using System;
using System.Collections.Generic;
using System.Text;
using NUnit.Framework;

namespace Acms.BllTests
{
    [TestFixture]
    public class SiteTest
    {
        [SetUp]
        public void SetUp()
        {
            Assert.AreEqual(0, Helper.GetRowCount(TableName));
        }

        [TearDown]
        public void TearDown()
        {
            Assert.AreEqual(0, Helper.GetRowCount(TableName));
        }

        private const string TableName = "Sites";

        public static int CreateRow(string name, string root, bool deleted)
        {
            System.Collections.Hashtable table = new System.Collections.Hashtable();
            table["Name"] = name;
            table["Root"] = root;
            table["Deleted"] = deleted ? 1 : 0;
            int id = 0;

            Helper.CreateSqlRow(TableName, table, ref id);

            return id;

        }

        public static bool FindRow(int id, string name, string root)
        {
            System.Collections.Hashtable table = new System.Collections.Hashtable();
            table["Id"] = id;
            table["Name"] = name;
            table["Root"] = root;

            return Helper.FindSqlRow(TableName, table);
        }

        public static void DeleteRow(int id)
        {
            Helper.DeleteSqlRow(TableName, "Id", id);
        }


        [Test]
        public void CreateInstanceTest()
        {
            Bll.Site site = Bll.Site.CreateInstance();
            Assert.IsNotNull(site);
        }

        [Test]
        public void NameTest()
        {
            string expected = "Test";
            Bll.Site site = Bll.Site.CreateInstance();
            site.Name = expected;
            Assert.AreEqual(site.Name, expected);
        }

        [Test]
        public void RootTest()
        {
            string expected = "Test";
            Bll.Site site = Bll.Site.CreateInstance();
            site.Root = expected;
            Assert.AreEqual(site.Root, expected);
        }

        [Test]
        public void GetAllTest()
        {
            List<int> ids = new List<int>();
            ids.Add(CreateRow("Test1", "localhost/Test1", false));
            ids.Add(CreateRow("Test2", "localhost/Test2", false));
            ids.Add(CreateRow("Test3", "localhost/Test3", false));
            ids.Add(CreateRow("Test4", "localhost/Test4", false));
            ids.Add(CreateRow("Test5", "localhost/Test5", true));

            List<Bll.Site> sites = Bll.Site.GetAll();
            Assert.IsNotNull(sites);
            Assert.AreEqual(ids.Count - 1, sites.Count);
            Assert.AreEqual(ids[0], sites[0].Id);
            Assert.AreEqual("Test1", sites[0].Name);
            Assert.AreEqual("localhost/Test1", sites[0].Root);
            Assert.IsNotNull(sites[0].ConcurencyId);

            foreach (int id in ids)
            {
                DeleteRow(id);
            }
        }

        [Test]
        public void GetByIdTest()
        {
            int id = CreateRow("Test1", "localhost/Test1", false);
            Bll.Site site = Bll.Site.GetById(id);
            Assert.IsNotNull(site);
            Assert.AreEqual(id, site.Id);
            Assert.AreEqual("Test1", site.Name);
            Assert.AreEqual("localhost/Test1", site.Root);
            Assert.IsNotNull(site.ConcurencyId);
            DeleteRow(id);
        }

        [Test]
        public void GetByIdDeletedTest()
        {
            Bll.Site site = Bll.Site.GetById(1);
            Assert.IsNull(site);
        }

        [Test]
        public void InsertTest()
        {
            int id = -1;
            try
            {
                string name = "InsertTestName";
                string root = "InsertTestRoot";
                Bll.Site site = Bll.Site.CreateInstance();
                site.Name = name;
                site.Root = root;
                site.Update();
                id = site.Id;
                Assert.Less(0, site.Id);
                Assert.IsNotNull(site.ConcurencyId);
                Assert.IsTrue(FindRow(site.Id, site.Name, site.Root));
            }
            finally
            {
                //delete Record
                DeleteRow(id);
            }
        }

        [Test]
        public void UpdateTest()
        {
            string originalName = null;
            string expectedName = "UpdateTestName";

            string originalRoot = null;
            string expectedRoot = "UpdateTestRoot";

            Bll.Site site = Bll.Site.GetById(10);
            Assert.IsNotNull(site);

            originalName = site.Name;
            originalRoot = site.Root;

            site.Name = expectedName;
            site.Root = expectedRoot;

            site.Update();

            Assert.AreEqual(expectedName, site.Name);
            Assert.AreEqual(expectedRoot, site.Root);

            site.Name = originalName;
            site.Root = originalRoot;

            site.Update();

            Assert.AreNotEqual(expectedName, site.Name);
            Assert.AreNotEqual(expectedRoot, site.Root);
        }

        [Test]
        public void DeleteTest()
        {
            int id = CreateRow("DeleteTestName", "DeleteTestRoot", true);
            try
            {
                Assert.Less(0, id);

                Bll.Site site = Bll.Site.GetById(id);
                Assert.IsNotNull(site);
                site.Delete();

                site = Bll.Site.GetById(id);
                Assert.IsNull(site);
            }
            finally
            {
                DeleteRow(id);
            }
        }

        [Test]
        [ExpectedException(typeof(Exceptions.ConcurencyException))]
        public void ConcurencyTest()
        {
            int id = CreateRow("ConcurencyName", "ConcurencyRow", false);
            try
            {
                Bll.Site site1 = Bll.Site.GetById(id);
                Bll.Site site2 = Bll.Site.GetById(id);
                site1.Name = "NEW NAME";
                site1.Update();

                site2.Name = "Should Fail";
                site2.Update();

            }
            finally
            {
                DeleteRow(id);
            }
        }

    }
}
